﻿using System;
using System.Text.RegularExpressions;

namespace LdtJudge.DataEngine.Common.DateAssemble
{
    /// <summary>
    /// 金额转换
    /// Class AmountConvert.
    /// </summary>
    public class AmountConvert
    {
        /// <summary>
        /// 将金额不论是大写还是小写都统一转换成小写
        /// Datas the convert number.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="IsConvertCmy">是否转大写.</param>
        /// <returns>System.String.</returns>
        public string DataConvertNumber(string text, bool IsConvertCmy)
        {
            Regex reg = new Regex("^[0-9]+$");
            Match ma = reg.Match(text);
            if (ma.Success && !IsConvertCmy)
                return text; //如果当前是纯数字，则直接返回



            text = Regex.Replace(text, "(元整?)($|\\s)", "");//将不需要的字符进行剔除
            var ss = Regex.Match(text, @"(^[1-9]|^0(?![^.]*\d))[^,.，]*[,.，].*\d*(?<![\u4e00-\u9fa5])$").Value;//进行匹配纯数字 
                                                                                                              // var s= Regex.Match(text,@"^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$").Value;//该条正则不是特别完整
            if (text.Length == ss.Length)
            {//如果传入的长度和匹配后的数字长度一致，则返回默认数值;
                if (IsConvertCmy)
                    text = CmycurD(text);
                return text;
            }
            //进行判断是否即包含数字又包含汉字
            string te = ConvertToNumber(text);
            if (!string.IsNullOrEmpty(te))
            {
                if (IsConvertCmy)
                    te = CmycurD(te);
                return te;
            }
            else
            {//则表示应该为全大写字符的。
                string num = CapitalCovertSmall(text);
                if (!string.IsNullOrEmpty(num))
                {
                    if (IsConvertCmy)
                        num = CmycurD(num);
                    return num;
                }
            }

            return text;
        }

        #region 进行处理即包含数字也包含汉字的，进行转换
        /// <summary>
        /// 将包含的既有数字又有汉字的进行处理
        /// Converts to number.
        /// ljx 2020-01-08 修改关于转换数据时小数位缺失问题 业务部门提的需求
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns>System.String.</returns>
        protected string ConvertToNumber(string text)
        {
            // var sh = Regex.Match(text, @"^(\d*(\.\d)?[亿|万|仟|千|佰|百|拾|十])*").Value;//这里用于匹配即有数字又有汉字单位的 //^(\d*(\.\d)?[亿|万|仟|千|佰|百|拾|十])*
            MatchCollection macs = Regex.Matches(text, @"(\d+([,.]\d*)?[十拾百佰千仟万亿])");
            //long tempnumber = 0;
            double tempnumber = 0;
            for (int i = 0; i < macs.Count; i++)
            {//这里表示即有数字又有汉字单位
                string tempstr = macs[i].Value;
                //进行截取数字部分
                string numsstr = Regex.Match(tempstr, @"(\d+([,.]\d)?)*").Value;
                double danwei = CharToUnit(tempstr[tempstr.Length - 1]);
                //tempnumber +=Convert.ToInt64(danwei*Convert.ToDouble(numsstr));
                tempnumber += danwei * Convert.ToDouble(numsstr);
                tempnumber=Convert.ToDouble(tempnumber.ToString("0.00"));
            }
            if (tempnumber > 0)
                return tempnumber.ToString();
            return string.Empty;
        }
        #endregion

        #region 小写金额转大写
        /// <summary>
        /// 转换人民币大小金额
        /// </summary>
        /// <param name="num">金额</param>
        /// <returns>返回大写形式</returns>
        private string CmycurD(decimal num)
        {
            string str1 = "零壹贰叁肆伍陆柒捌玖";            //0-9所对应的汉字
            string str2 = "万仟佰拾亿仟佰拾万仟佰拾元角分"; //数字位所对应的汉字
            string str3 = "";    //从原num值中取出的值
            string str4 = "";    //数字的字符串形式
            string str5 = "";  //人民币大写金额形式
            int i;    //循环变量
            int j;    //num的值乘以100的字符串长度
            string ch1 = "";    //数字的汉语读法
            string ch2 = "";    //数字位的汉字读法
            int nzero = 0;  //用来计算连续的零值是几个
            int temp;            //从原num值中取出的值

            num = Math.Round(Math.Abs(num), 2);    //将num取绝对值并四舍五入取2位小数
            str4 = ((long)(num * 100)).ToString();        //将num乘100并转换成字符串形式
            j = str4.Length;      //找出最高位
            if (j > 15) { return "溢出"; }
            str2 = str2.Substring(15 - j);   //取出对应位数的str2的值。如：200.55,j为5所以str2=佰拾元角分

            //循环取出每一位需要转换的值
            for (i = 0; i < j; i++)
            {
                str3 = str4.Substring(i, 1);          //取出需转换的某一位的值
                temp = Convert.ToInt32(str3);      //转换为数字
                if (i != (j - 3) && i != (j - 7) && i != (j - 11) && i != (j - 15))
                {
                    //当所取位数不为元、万、亿、万亿上的数字时
                    if (str3 == "0")
                    {
                        ch1 = "";
                        ch2 = "";
                        nzero = nzero + 1;
                    }
                    else
                    {
                        if (str3 != "0" && nzero != 0)
                        {
                            ch1 = "零" + str1.Substring(temp * 1, 1);
                            ch2 = str2.Substring(i, 1);
                            nzero = 0;
                        }
                        else
                        {
                            ch1 = str1.Substring(temp * 1, 1);
                            ch2 = str2.Substring(i, 1);
                            nzero = 0;
                        }
                    }
                }
                else
                {
                    //该位是万亿，亿，万，元位等关键位
                    if (str3 != "0" && nzero != 0)
                    {
                        ch1 = "零" + str1.Substring(temp * 1, 1);
                        ch2 = str2.Substring(i, 1);
                        nzero = 0;
                    }
                    else
                    {
                        if (str3 != "0" && nzero == 0)
                        {
                            ch1 = str1.Substring(temp * 1, 1);
                            ch2 = str2.Substring(i, 1);
                            nzero = 0;
                        }
                        else
                        {
                            if (str3 == "0" && nzero >= 3)
                            {
                                ch1 = "";
                                ch2 = "";
                                nzero = nzero + 1;
                            }
                            else
                            {
                                if (j >= 11)
                                {
                                    ch1 = "";
                                    nzero = nzero + 1;
                                }
                                else
                                {
                                    ch1 = "";
                                    ch2 = str2.Substring(i, 1);
                                    nzero = nzero + 1;
                                }
                            }
                        }
                    }
                }
                if (i == (j - 11) || i == (j - 3))
                {
                    //如果该位是亿位或元位，则必须写上
                    ch2 = str2.Substring(i, 1);
                }
                str5 = str5 + ch1 + ch2;

                if (i == j - 1 && str3 == "0")
                {
                    //最后一位（分）为0时，加上“整”
                    str5 = str5 + '整';
                }
            }
            if (num == 0)
            {
                str5 = "零元整";
            }
            return str5;
        }

        /**/
        /// <summary>
        /// 一个重载，将字符串先转换成数字在调用CmycurD(decimal num)
        /// </summary>
        /// <param name="num">用户输入的金额，字符串形式未转成decimal</param>
        /// <returns>将阿拉伯数字转换成大写数字</returns>
        public string CmycurD(string numstr)
        {
            try
            {
                decimal num = Convert.ToDecimal(numstr);
                return CmycurD(num);
            }
            catch
            {
                return "非数字形式！";
            }
        }

        #endregion

        #region 大写金额转小写阿拉伯数字


        /// <summary>
        /// 大写金额转阿拉伯数字
        /// Capitals the covert small.
        /// </summary>
        /// <param name="daxie">The daxie.</param>
        /// <returns>System.String.</returns>
        protected string CapitalCovertSmall(string daxie)
        {//壹拾陆万伍仟
            return ParseCnToInt(daxie).ToString();
        }


        /// <summary>
        /// 大写汉子转换数字
        /// </summary>
        /// <param name="c">The c.</param>
        /// <returns>System.Int64.</returns>
        private long CharToNumber(char c)
        {
            switch (c)
            {
                case '一': return 1;
                case '壹': return 1;
                case '俩': return 2;
                case '两': return 2;
                case '二': return 2;
                case '贰': return 2;
                case '三': return 3;
                case '叁': return 3;
                case '四': return 4;
                case '肆': return 4;
                case '五': return 5;
                case '伍': return 5;
                case '六': return 6;
                case '陆': return 6;
                case '七': return 7;
                case '柒': return 7;
                case '八': return 8;
                case '捌': return 8;
                case '九': return 9;
                case '玖': return 9;
                case '零': return 0;
                default: return -1;
            }
        }

        /// <summary>
        /// 转换单位
        /// </summary>
        /// <param name="c">The c.</param>
        /// <returns>System.Int64.</returns>
        private double CharToUnit(char c)
        {
            switch (c)
            {
                case '厘': return 0.001;
                case '分': return 0.01;
                case '角': return 0.1;
                case '元': return 1;
                case '十': return 10;
                case '拾': return 10;
                case '百': return 100;
                case '佰': return 100;
                case '千': return 1000;
                case '仟': return 1000;
                case '万': return 10000;
                case '萬': return 10000;
                case '亿': return 100000000;
                default: return 0.0000;
            }
        }


        /// <summary>
        /// 将中文数字转换阿拉伯数字
        /// (?<=^)壹(?=拾)
        /// </summary>
        /// <param name="cnum">汉字数字</param>
        /// <returns>长整型阿拉伯数字</returns>
        protected string ParseCnToInt(string cnum)
        {
            cnum = Regex.Replace(cnum, "\\s+", "");
            double firstUnit = 0.0001;//一级单位                  
            double secondUnit = 1;//二级单位   
            double tmpUnit = 0.001;//临时单位变量  
            double result = 0;//结果  
            for (int i = cnum.Length - 1; i > -1; --i)//从低到高位依次处理  
            {
                tmpUnit = CharToUnit(cnum[i]);//取出此位对应的单位  
                if (tmpUnit > firstUnit)//判断此位是数字还是单位  
                {
                    firstUnit = tmpUnit;//是的话就赋值,以备下次循环使用  
                    secondUnit = 1;
                    if (i == 0)//处理如果是"十","十一"这样的开头的  
                    {
                        result += firstUnit * secondUnit;
                    }
                    continue;//结束本次循环  
                }
                else if (tmpUnit == 10 && i == 0)
                {//表示结束未是十或拾
                    result += firstUnit * tmpUnit;
                }
                else if (tmpUnit > secondUnit)
                {//表示为数字
                    secondUnit = tmpUnit;
                    continue;
                }
                else
                {
                    var number = CharToNumber(cnum[i]);
                    if (number > -1)
                    {
                        if (firstUnit == 0.0001)
                        {
                            firstUnit = 1;
                        }
                        result += firstUnit * secondUnit * number;//如果是数字,则和单位想乘然后存到结果里  
                    }
                    else
                    {
                        return cnum;
                    }

                }

            }
            //将原来转换数字小数点后面保留两位去掉；要素分析组需求；
            //return result.ToString("0.00");
            return result.ToString();
        }

        ///// <summary>
        ///// 将中文数字转换阿拉伯数字
        ///// </summary>
        ///// <param name="cnum">汉字数字</param>
        ///// <returns>长整型阿拉伯数字</returns>
        //protected  long ParseCnToInt(string cnum)
        //{
        //    cnum = Regex.Replace(cnum, "\\s+", "");
        //    long firstUnit = 1;//一级单位                  
        //    long secondUnit = 1;//二级单位   
        //    long tmpUnit = 1;//临时单位变量  
        //    long result = 0;//结果  
        //    for (int i = cnum.Length - 1; i > -1; --i)//从低到高位依次处理  
        //    {
        //        tmpUnit = CharToUnit(cnum[i]);//取出此位对应的单位  
        //        if (tmpUnit > firstUnit)//判断此位是数字还是单位  
        //        {
        //            firstUnit = tmpUnit;//是的话就赋值,以备下次循环使用  
        //            secondUnit = 1;
        //            if (i == 0)//处理如果是"十","十一"这样的开头的  
        //            {
        //                result += firstUnit * secondUnit;
        //            }
        //            continue;//结束本次循环  
        //        }
        //        else if (tmpUnit == 10 && i == 0)
        //        {
        //            result += firstUnit * tmpUnit;
        //        }
        //        else if (tmpUnit > secondUnit)//表示为数字
        //        {
        //            secondUnit = tmpUnit;
        //            continue;
        //        }
        //        else
        //        result += firstUnit * secondUnit * CharToNumber(cnum[i]);//如果是数字,则和单位想乘然后存到结果里  
        //    }
        //    return result;
        //}

        #endregion
    }
}
